package edu.kufpg.armatus.networking; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; import org.apache.http.HttpException; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.NoHttpResponseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.HttpHostConnectException; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import edu.kufpg.armatus.AsyncActivityTask; import edu.kufpg.armatus.console.ConsoleActivity; /** * Task that connects to a server running HERMIT-web and simulates HERMIT commands * by using HTTP GET and POST requests. */ public abstract class HermitHttpServerRequest<Result> extends AsyncActivityTask<ConsoleActivity, String, Void, Result> { private HttpRequest mRequest; private String mErrorMessage; /** * Constructs a new instance. The constructor is not the place to put any input * {@link JSONObject}s (do that in {@link android.os.AsyncTask#execute(JSONObject...) * execute(JSONObject...)} instead). * @param console reference to the current console. */ public HermitHttpServerRequest(ConsoleActivity console, HttpRequest request) { super(console); mRequest = request; } @Override protected void onPreExecute() { super.onPreExecute(); getActivity().setProgressBarVisibility(true); getActivity().disableInput(true); } @Override protected Result doInBackground(String... params) { HttpClient httpClient = null; HttpResponse httpResponse = null; String responseStr = null; try { final HttpParams httpParams = new BasicHttpParams(); //Set timeout length to 10 seconds HttpConnectionParams.setConnectionTimeout(httpParams, 10000); HttpConnectionParams.setSoTimeout(httpParams, 10000); httpClient = new DefaultHttpClient(httpParams); HttpUriRequest request = null; if (mRequest.equals(HttpRequest.GET)) { request = new HttpGet(params[0]); } else if (mRequest.equals(HttpRequest.POST)) { final HttpPost httpPost = new HttpPost(params[0]); if (params.length > 1) { httpPost.setHeader("content-type", "application/json"); if (params[1] != null && !params[1].isEmpty()) { try { httpPost.setEntity(new StringEntity(params[1])); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } request = httpPost; } if (!isCancelled()) { httpResponse = httpClient.execute(request); } if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { final String entity = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8).trim(); if (entity != null) { responseStr = entity; } } else { throw new HttpException("Error code " + httpResponse.getStatusLine().getStatusCode()); } } catch (HttpException e) { return cancelResult(e, "ERROR: server problem (" + httpResponse.getStatusLine().getStatusCode() + ")."); } catch (HttpHostConnectException e) { return cancelResult(e, "ERROR: server connection refused."); } catch (ClientProtocolException e) { return cancelResult(e, "ERROR: client protocol problem."); } catch (NoHttpResponseException e) { return cancelResult(e, "ERROR: the target server failed to respond."); } catch (ConnectTimeoutException e) { return cancelResult(e, "ERROR: the server connection timed out."); } catch (SocketTimeoutException e) { return cancelResult(e, "ERROR: the server connection timed out."); } catch (IOException e) { return cancelResult(e, "ERROR: I/O problem."); } finally { httpClient.getConnectionManager().shutdown(); } return onResponse(responseStr); } @Override protected void onPostExecute(Result result) { super.onPostExecute(result); end(); } @Override protected void onCancelled(Result error) { super.onCancelled(error); if (mErrorMessage != null && getActivity() != null) { getActivity().appendErrorResponse(mErrorMessage); } end(); } private void end() { if (getActivity().getHermitClient().isRequestDelayed()) { getActivity().getHermitClient().notifyDelayedRequestFinished(); } getActivity().enableInput(); getActivity().setProgressBarVisibility(false); } private Result cancelResult(Exception error, String errorMsg) { error.printStackTrace(); mErrorMessage = errorMsg; cancel(true); return null; } protected abstract Result onResponse(String response); protected String getErrorMessage() { return mErrorMessage; } protected void setErrorMessage(String message) { mErrorMessage = message; } public enum HttpRequest { GET, POST } }